﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Assets.entities;

namespace Assets.entities {
    
    public struct MarchingCube {

        public static MarchingCube full = new MarchingCube(true, true, true, true, true, true, true, true);
        public static MarchingCube empty = new MarchingCube(false, false, false, false, false, false, false, false);

        private BitArray _bits;
        private byte _type;

        public MarchingCube(bool tbl, bool tbr, bool tfr, bool tfl, bool bbl, bool bbr, bool bfr, bool bfl) {
            this._bits = new BitArray(new bool[8] { tbl, tbr, tfr, tfl, bbl, bbr, bfr, bfl});

            byte[] bytes = new byte[1];
            this._bits.CopyTo(bytes, 0);
            this._type =  bytes[0];
        }

        public byte type {
            get {
                return this._type;
            }
        }

        public bool topBackLeftBit {
            get {
                return this._bits.Get(0);
            }
        }

        public bool topBackRightBit {
            get {
                return this._bits.Get(1);
            }
        }

        public bool topFrontRightBit {
            get {
                return this._bits.Get(2);
            }
        }

        public bool topFrontLeftBit {
            get {
                return this._bits.Get(3);
            }
        }

        public bool bottomBackLeftBit {
            get {
                return this._bits.Get(4);
            }
        }

        public bool bottomBackRightBit {
            get {
                return this._bits.Get(5);
            }
        }

        public bool bottomFrontRightBit {
            get {
                return this._bits.Get(6);
            }
        }

        public bool bottomFrontLeftBit {
            get {
                return this._bits.Get(7);
            }
        }

        public string ToString() {
            StringBuilder sb = new StringBuilder();
            foreach (var b in this._bits) {
                sb.Append((bool)b ? "1" : "0");
            }
            return sb.ToString();
        }

        public bool isFull {
            get {
                return this._type == 255;
            }
        }

        public bool isEmpty {
            get {
                return this._type == 0;
            }
        }

        public bool isIsosurface {
            get {
                return !this.isFull && !this.isEmpty;
            }
        }



        public MarchingSquare topMarchingSquare {
            get {
                return new MarchingSquare(
                    this._bits.Get(0), 
                    this._bits.Get(1), 
                    this._bits.Get(2), 
                    this._bits.Get(3)
                );
            }
        }



        public MarchingSquare bottomMarchingSquare {
            get {
                return new MarchingSquare(
                    this._bits.Get(7),
                    this._bits.Get(6),
                    this._bits.Get(5),
                    this._bits.Get(4)
                );
            }
        }



        public MarchingSquare frontMarchingSquare {
            get {
                return new MarchingSquare(
                    this.topFrontLeftBit,
                    this.topFrontRightBit,
                    this.bottomFrontRightBit,
                    this.bottomFrontLeftBit
                );
            }
        }



        public MarchingSquare backMarchingSquare {
            get {
                return new MarchingSquare(
                    this._bits.Get(1),
                    this._bits.Get(0),
                    this._bits.Get(5),
                    this._bits.Get(4)
                );
            }
        }



        public MarchingSquare rightMarchingSquare {
            get {
                return new MarchingSquare(
                    this._bits.Get(2),
                    this._bits.Get(1),
                    this._bits.Get(5),
                    this._bits.Get(6)
                );
            }
        }



        public MarchingSquare leftMarchingSquare {
            get {
                return new MarchingSquare(
                    this._bits.Get(0),
                    this._bits.Get(3),
                    this._bits.Get(7),
                    this._bits.Get(4)
                );
            }
        }
        
    }
}
